package org.ranshiyan.utils;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

import java.security.KeyPair;

import static Enums.SignTypeEnum.SM2;

public class Sm2Utils {

    public static String publicKey ="BB34D657EE7E8490E66EF577E6B3CEA28B739511E787FB4F71B7F38F241D87F18A5A93DF74E90FF94F4EB907F271A36B295B851F971DA5418F4915E2C1A23D6E";
    public static String privateKey = "0B1CE43098BC21B8E82B5C065EDB534CB86532B1900A49D49F3C53762D2997FA";

    public static SM2 getPublicSm2(String publicKey) throws Exception {
        if(publicKey.length() != 128){
            throw new Exception("Wrong publickey length");
        }
        String pubx = publicKey.substring(0,64);
        String puby = publicKey.substring(64,128);
        SM2 pubSM2 =new SM2(null, pubx,puby);
        return pubSM2;
    }

    public static SM2 getPrivateSm2(String privateKey){
        SM2 prvSM2 =new SM2(privateKey, null,null);
        return prvSM2;
    }

    public static String sign(String source,String privateKey){
        SM2 prvSM2 = Sm2Utils.getPrivateSm2(privateKey);
        String sign= Base64Encoder.encode(prvSM2.sign(source.getBytes()));
        return sign;
    }

    public static boolean verify(String source,String sign,String publicKey) throws Exception {
        SM2 pubSM2 = Sm2Utils.getPublicSm2(publicKey);
        return pubSM2.verify(source.getBytes(), Base64Decoder.decode(sign));
    }

    public static String encrypt(String source, String publicKey) throws Exception {
        SM2 pubSM2 = Sm2Utils.getPublicSm2(publicKey);
        String enparams = pubSM2.encryptBcd(source, KeyType.PublicKey);
        return enparams;
    }

    public static String decrypt(String source, String privateKey) throws Exception {
        SM2 prvSM2 = Sm2Utils.getPrivateSm2(privateKey);
        String deparams= prvSM2.decryptStrFromBcd(source,KeyType.PrivateKey);
        return deparams;
    }

    public static void generateKeyPair(){
        KeyPair encrypt_pair1 = SecureUtil.generateKeyPair("SM2");
        String pubkey = HexUtil.encodeHexStr(((BCECPublicKey)encrypt_pair1.getPublic()).getQ().getEncoded(false)).substring(2);
        String prvkey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(encrypt_pair1.getPrivate()));
        System.out.println("公钥:" + pubkey);
        System.out.println("私钥:" + prvkey);
    }

    public static void main(String[] args) throws Exception {
        KeyPair encrypt_pair1 = SecureUtil.generateKeyPair("SM2");
        String pubkey = HexUtil.encodeHexStr(((BCECPublicKey)encrypt_pair1.getPublic()).getQ().getEncoded(false)).substring(2);
        String prvkey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(encrypt_pair1.getPrivate()));
        System.out.println("公钥:" + pubkey);
        System.out.println("私钥:" + prvkey);

        System.out.println(verify("1",sign("1",prvkey),pubkey));
    }
}
